package com.ly.mp.busicen.rule.flow.filter.plugin;

import static com.ly.mp.busicen.rule.XruleStrUtils.splitXKH;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.google.common.base.Strings;
import com.ly.mp.busicen.common.context.ListResult;
import com.ly.mp.busicen.rule.field.msg.IFieldMsgContainer;
import com.ly.mp.busicen.rule.flow.FlowSpelUtil;
import com.ly.mp.busicen.rule.flow.action.ActionResult;
import com.ly.mp.busicen.rule.flow.action.IActionResult;
import com.ly.mp.busicen.rule.flow.action.IActionResult.Signal;
import com.ly.mp.busicen.rule.flow.action.OperationType;
import com.ly.mp.busicen.rule.flow.filter.FlowFilterBase;
import com.ly.mp.busicen.rule.flow.filter.FlowInvocation;
import com.ly.mp.busicen.rule.flow.filter.FlowResult;

@Component
public class ReadLogFilter extends FlowFilterBase {

	Logger log = LoggerFactory.getLogger(ReadLogFilter.class);
	
	@Autowired
	IFieldMsgContainer fieldMsgContainer;
	
	@SuppressWarnings("rawtypes")
	@Override
	public FlowResult doInvoke(FlowInvocation invocation) {
		String paramStr = splitXKH(invocation.statement());
		FlowResult result = invocation.invoker().invoke(invocation);
		//SCRIPT类型的流程结果由SCRIPT流程解析器自己判定
		if (result.actionResult().signal().equals(Signal.CONTINUE) 
				&& !invocation.action().operation().equals(OperationType.SCRIPT)) {
			if (result.actionResult().data() == null) {
				((ActionResult) result.actionResult()).setSignal(Signal.BREAK);
				log.info("流程【{}】节点【{}】结果改为中断，因结果为null",invocation.flowVolume().flow(),invocation.action().action());
				setErrorLogMsg(invocation, result, paramStr);
				return result;				
			}
			if (invocation.action().operation().equals(OperationType.INSERT)
					|| invocation.action().operation().equals(OperationType.UPDATE)
					|| invocation.action().operation().equals(OperationType.DELETE)) {
				
				if (result.actionResult().data() instanceof Integer) {
					Integer count = result.actionResult().data();
					if (count == 0) {
						((ActionResult) result.actionResult()).setSignal(Signal.BREAK);
						log.info("流程【{}】节点【{}】结果改为中断，因结果为0",invocation.flowVolume().flow(),invocation.action().action());
						setErrorLogMsg(invocation, result, paramStr);
					}
				}
				if (result.actionResult().data() instanceof LinkedList) {
					LinkedList<IActionResult> resultList = result.actionResult().data();
					for (IActionResult iActionResult : resultList) {
						if (iActionResult.signal()==Signal.CONTINUE&&iActionResult.data()!=null&&iActionResult.data() instanceof Integer) {
							int count = (Integer)iActionResult.data();
							if (count == 0) {
								((ActionResult) result.actionResult()).setSignal(Signal.BREAK);
								log.info("流程【{}】节点【{}】结果改为中断，因结果结果集合中存在某一结果为0",invocation.flowVolume().flow(),invocation.action().action());								
								setErrorLogMsg(invocation, result, paramStr);
								break;
							}
						}
					}
				}
				
			}
			if (invocation.action().operation().equals(OperationType.SELECTLIST)
					|| invocation.action().operation().equals(OperationType.SELECTONE)
					|| invocation.action().operation().equals(OperationType.SPBEAN)) {
				Object data = result.actionResult().data();
				if (data instanceof List && ((List) data).isEmpty()) {
					((ActionResult) result.actionResult()).setSignal(Signal.BREAK);
					log.info("流程【{}】节点【{}】结果改为中断，因结果集合为空",invocation.flowVolume().flow(),invocation.action().action());
					setErrorLogMsg(invocation, result, paramStr);
				}
				if (data instanceof ListResult && ((ListResult) data).getRows().isEmpty()) {
					((ActionResult) result.actionResult()).setSignal(Signal.BREAK);
					log.info("流程【{}】节点【{}】结果改为中断，因分页结果为空",invocation.flowVolume().flow(),invocation.action().action());
					setErrorLogMsg(invocation, result, paramStr);
				}
				if(data instanceof Map && ((Map)data).values().size()==1&& "0".equals(String.valueOf(((Map)data).values().iterator().next()))) {
					((ActionResult) result.actionResult()).setSignal(Signal.BREAK);
					log.info("流程【{}】节点【{}】结果改为中断，因结果为0",invocation.flowVolume().flow(),invocation.action().action());
					setErrorLogMsg(invocation, result, paramStr);
				}
			}
		}else if (result.actionResult().signal().equals(Signal.BREAK)) {
			setErrorLogMsg(invocation, result, paramStr);
		}
		return result;
	}
	/**
	 * 设置错误日志信息
	 */
	private void setErrorLogMsg(FlowInvocation invocation,FlowResult result,String paramStr) {
		ActionResult actionResult = (ActionResult) result.actionResult();
		actionResult.setMsg(getLogMsg(invocation,paramStr));
		actionResult.setSignal(Signal.BREAK);
		actionResult.setConvertMsg(false);
	}
	/**
	 * 获取日志消息
	 */
	private String getLogMsg(FlowInvocation invocation,String paramStr) {
		List<String> params = Stream.of(paramStr.split(",")).filter(m->!StringUtils.isEmpty(m)).collect(Collectors.toList());
		//IDataVolume data = invocation.dataVolume();
		String msgId = params.get(0);
		List<Object> list = new ArrayList<>();
		for(int i = 1;i < params.size();i++) {
			String param = params.get(i);
			list.add(FlowSpelUtil.spelGetData(invocation.action(), param));// FlowFilter.getDataFromContextSpel(data, param));
		}
//		String msg = LoggerHelper.getMsg(msgId,list.toArray());
		String msg = fieldMsgContainer.getMsg(null, msgId).getMsg();
		msg = Strings.lenientFormat(msg, list.toArray());
		log.info("流程【{}】节点【{}】结果中断，读取日志【{}】",invocation.flowVolume().flow(),invocation.action().action(),msg);
		return msg;
	}
	
	@Override
	public String fileterName() {
		return "readlog";
	}
}
